﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DTO.Clases;
using Aplicacion.Configuracion.Marcas;
using BussinesLayer.Clases;
using System.Collections;
using Utilities;
using CustomControl;

namespace Aplicacion.Inventario.Producto
{
    public partial class frmEditarProducto : Form
    {
        #region Atributos

        /// <summary>
        /// Obtiene o establece los datos del Producto.
        /// </summary>
        private DTO.Clases.Producto ProductoOriginal { set; get; }

        /// <summary>
        /// Obtiene o establece los datos del Producto Editado.
        /// </summary>
        private DTO.Clases.Producto ProductoEditado { set; get; }

        /// <summary>
        /// Representa una Lista de los Descuentos de Producto.
        /// </summary>
        private List<Descuento> Descuentos;

        /// <summary>
        /// Representa una Lista de los Recargos del Producto.
        /// </summary>
        private List<Recargo> Recargos;

        /// <summary>
        /// Obtiene o establece el valor del Codigo Interno del Producto.
        /// </summary>
        public string CodigoProducto { set; get; }

        /// <summary>
        /// Obtiene o establece el Codigo de la Categoria del Producto
        /// </summary>
        private string CodigoCategoria;

        /// <summary>
        /// Obtiene o establece el Id de la Marca del Producto.
        /// </summary>
        private int IdMarca;

        /// <summary>
        /// Objeto de logica de negocio de Producto.
        /// </summary>
        private BussinesProducto miBussinesProducto;

        /// <summary>
        /// Objeto de logica de negocio de Descuento.
        /// </summary>
        private BussinesDescuento miBussinesDescuento;

        /// <summary>
        /// Objeto de logica de negocio de Recargo.
        /// </summary>
        private BussinesRecargo miBussinesRecargo;

        /// <summary>
        /// Objeto de logica de negocio de Iva.
        /// </summary>
        private BussinesIva miBussinesIva;

        /// <summary>
        /// Objeto de logica de negocio de Color.
        /// </summary>
        private BussinesColor miBussinesColor;

        /// <summary>
        /// Objeto de logica de negocio de Inventario.
        /// </summary>
        private BussinesInventario miBussinesInventario;

        /// <summary>
        /// Objeto de logica de negocio de Unidad de Medida.
        /// </summary>
        private BussinesUnidadMedida miBussinesUnidad;

        /// <summary>
        /// Objeto de logica de negocio de Valor de Unidad de Medida.
        /// </summary>
        private BussinesValorUnidadMedida miBussinesMedida;

        #endregion

        #region Utilidades

        /// <summary>
        /// Objeto para el uso de AplicaPrecio.
        /// </summary>
        private AplicarPrecio aplicaPrecio;

        /// <summary>
        /// Obtiene o establece el valor que indica si se configuro color para el formulario
        /// </summary>
        private bool EnableColor;

        /// <summary>
        /// Objeto para que el usuario seleccione un color.
        /// </summary>
        private ColorDialog miColorDialog;

        /// <summary>
        /// Establece la carpeta temporal donde se almacenara la imagen.
        /// </summary>
        private const string folder = "C:\\ImagesTemp";

        /// <summary>
        /// Establece el nombre y extencion de la imagen que se almacenara. Por defecto es .JPEG.
        /// </summary>
        private const string file = "temp.jpg";

        /// <summary>
        /// Estabelce la ruta y el nombre del archivo completo.
        /// </summary>
        private const string rutaYArchivo = folder + "\\" + file;

        #endregion

        #region Utilidades de Validacion

        /// <summary>
        /// Objeto para mostrar errores de validacion al usuario.
        /// </summary>
        private ErrorProvider miError;

        /// <summary>
        /// Establece la condicion para guardar.
        /// </summary>
        private bool codigoMatch = false,
                     barraMatch = false,
                     referenciaMatch = false,
                     nombreMatch = false,
                     descripcionMatch = false,
                     utilidadMatch = false,
                     valorVentaMatch = false,
                     presentacionMatch = false,
                     minimaMatch = false,
                     maximaMatch = false;

        /// <summary>
        /// Representan mensajes de requerido o formato incorrecto
        /// </summary>
        private const string
            codigoRequerido = "El campo Codigo es Requerido.",
            nombreRequerido = "El campo Nombre es Requerido.",
            valorVentaRequerido = "El campo Valor de Venta es Requerido.",
            codigoFormato = "El Codigo que ingreso tiene formato incorrecto.",
            barraFormato = "El Codigo de Barras que ingreso tiene formato incorrecto.",
            referenciaFormato = "La Referencia que ingreso tiene formato incorrecto.",
            nombreFormato = "El NOmbre que ingreso tiene formato incorrecto.",
            descripcionFormato = "La Descripcion que ingreso tiene formato incorrecto.",
            utilidadFormato = "El valor de la Utilidad que ingreso tiene formato incorrecto.",
            valorVentaFormato = "El Valor de Venta que ingreso tiene formato incorrecto.",
            presentacionFormato = "El valor de la Presentacion que ingreso tiene formato incorrecto.",
            minimaFormato = "La cantidad Minima que ingreso tiene formato incorrecto.",
            maximaFormato = "La Cantidad Maxima que ingreso tiene formato incorrecto.",
            codigoExiste = "El codigo que ingreso ya existe en la base de datos.",
            barrasExiste = "El codigo de barras que ingreso ya existe en la base de datos.";

        /// <summary>
        /// Establece la condicion que indica si el usuario presiono el boton de salir.
        /// </summary>
        private bool PrestBtnSalir = false;

        #endregion

        public frmEditarProducto()
        {
            InitializeComponent();
            ProductoEditado = new DTO.Clases.Producto();
            EnableColor = Convert.ToBoolean(AppConfiguracion.ValorSeccion("color"));
            miBussinesProducto = new BussinesProducto();
            miBussinesDescuento = new BussinesDescuento();
            miBussinesRecargo = new BussinesRecargo();
            miBussinesIva = new BussinesIva();
            miBussinesColor = new BussinesColor();
            miBussinesInventario = new BussinesInventario();
            miBussinesUnidad = new BussinesUnidadMedida();
            miBussinesMedida = new BussinesValorUnidadMedida();
            miError = new ErrorProvider();
        }

        public void frmEditarProducto_Load(object sender, EventArgs e)
        {
            CargarProductoAEditar();
            CompletaEventos.Completam += new CompletaEventos.CompletaAccionm(CompletaEventos_Completo);
        }

        private void tsbGuardarCambiosEditarProducto_Click(object sender, EventArgs e)
        {
            ValidacionParaGuardar();
            if (codigoMatch &&
                barraMatch &&
                referenciaMatch &&
                nombreMatch &&
                descripcionMatch &&
                utilidadMatch &&
                valorVentaMatch &&
                presentacionMatch &&
                minimaMatch &&
                maximaMatch)
            {
                CargarProducto();
                try
                {
                    foreach (DataGridViewRow row in dgvMedida.Rows)
                    {
                        var inventario = new DTO.Clases.Inventario();
                        inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                        inventario.IdMedida = (int)row.Cells[0].Value;
                        if (!miBussinesInventario.ComprobarInventario(inventario, false))
                        {
                            miBussinesInventario.InsertarInventario(inventario);
                        }
                    }
                    miBussinesProducto.EditarProducto(ProductoEditado);
                    OptionPane.MessageInformation("Los datos se editaron correctamente.");
                }
                catch (Exception ex)
                {
                    OptionPane.MessageError(ex.Message);
                }
            }
        }

        private void tsbSalirEditarProducto_Click(object sender, EventArgs e)
        {
            DialogResult rta = MessageBox.Show("¿Desea guardar los cambios?", "Edicion",
                MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
            if (rta == DialogResult.Yes)
            {
                tsbGuardarCambiosEditarProducto_Click(null, null);
                if (codigoMatch &&
                    barraMatch &&
                    referenciaMatch &&
                    nombreMatch &&
                    descripcionMatch &&
                    utilidadMatch &&
                    valorVentaMatch &&
                    presentacionMatch &&
                    minimaMatch &&
                    maximaMatch)
                {
                    PrestBtnSalir = true;
                    this.Close();
                }
                else
                {
                    PrestBtnSalir = false;
                }
            }
            else
            {
                if (rta == DialogResult.No)
                {
                    CompletaEventos.CapturaEventom(false);
                    PrestBtnSalir = true;
                    this.Close();
                }
            }
        }

        private void frmEditarProducto_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!PrestBtnSalir)
            {
                DialogResult rta = MessageBox.Show("¿Desea guardar los cambios?", "Edicion",
                    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);
                if (rta == DialogResult.Yes)
                {
                    tsbGuardarCambiosEditarProducto_Click(null, null);
                    if (codigoMatch &&
                        barraMatch &&
                        referenciaMatch &&
                        nombreMatch &&
                        descripcionMatch &&
                        utilidadMatch &&
                        valorVentaMatch &&
                        presentacionMatch &&
                        minimaMatch &&
                        maximaMatch)
                    {
                        e.Cancel = false;
                    }
                    else
                        e.Cancel = true;
                }
                else
                {
                    if (rta == DialogResult.No)
                    {
                        e.Cancel = false;
                    }
                    else
                    {
                        e.Cancel = true;
                    }
                }
            }
            CompletaEventos.CapturaEventom(false);
        }

        private void lkGenerarCodigo_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {

        }

        private void lkGenerarBarras_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {

        }

        private void btnBuscarCategoria_Click(object sender, EventArgs e)
        {
            Categoria.FrmCategoria frmCategoria = new Categoria.FrmCategoria();
            frmCategoria.TblCategoria.SelectTab(1);
            frmCategoria.CargarGridCategorias();
            frmCategoria.Extencion = true;
            frmCategoria.Show();
        }

        private void btnBuscarMarca_Click(object sender, EventArgs e)
        {
            frmMarca cargamarca = new frmMarca();
            cargamarca.Extension = true;
            cargamarca.CargaGrillaMarca();
            cargamarca.Show();
        }

        private void btnEditarAplicaPrecio_Click(object sender, EventArgs e)
        {
            txtAplicaPrecio.Visible = false;
            cbAplicarPrecio.Visible = true;
            btnEditarAplicaPrecio.Enabled = false;
            cbAplicarPrecio.Focus();
        }

        private void btnEditarIva_Click(object sender, EventArgs e)
        {
            txtIva.Visible = false;
            cbIvaEditar.Visible = true;
            btnEditarIva.Enabled = false;
            cbIvaEditar.Focus();
        }

        private void dgvMedida_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvMedida.RowCount != 0)
            {
                var idMedida = (int)dgvMedida.CurrentRow.Cells["IdMedida"].Value;
                try
                {
                    dgvColor.DataSource = miBussinesProducto.ProductoConMedidaYcolor(CodigoProducto, idMedida);
                }
                catch (Exception ex)
                {
                    OptionPane.MessageError(ex.Message);
                }
            }
            else
                dgvColor.DataSource = null;
        }

        private void dgvMedida_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Up || e.KeyData == Keys.Down)
            {
                dgvMedida_CellClick(null, null);
            }
        }

        private void btnAddMedida_Click(object sender, EventArgs e)
        {
            if (dgvMedida.RowCount == 0)
            {
                dgvColor.Visible = false;
                btnAddColor.Visible = false;
                btnEliminarColor.Visible = false;

                CargarUnidadMedida();
                CargarListBoxTallas();
                gbSeleccionarMedida.Visible = true;
                dgvListaMedida.Visible = false;

                gbSeleccionarMedida.Size = new Size(320, 246);
                gbSeleccionarMedida.Controls.Add(lbUnidadMedida);
                gbSeleccionarMedida.Controls.Add(lbValorMedida);
                gbSeleccionarMedida.Controls.Add(lstbTalla);
                gbSeleccionarMedida.Controls.Add(rbtnTalla);
                gbSeleccionarMedida.Controls.Add(rbtnUnidadMedida);

                lbUnidadMedida.Size = new Size(100, 175);
                lbUnidadMedida.Location = new Point(16, 65);
                lbUnidadMedida.Visible = true;

                lbValorMedida.Size = new Size(100, 175);
                lbValorMedida.Location = new Point(128, 65);
                lbValorMedida.Visible = true;

                lstbTalla.Size = new Size(60, 175);
                lstbTalla.Location = new Point(250, 65);
                lstbTalla.Visible = true;
                lstbTalla.Enabled = false;

                rbtnUnidadMedida.Location = new Point(16, 40);
                rbtnUnidadMedida.Visible = true;
                rbtnUnidadMedida.Checked = true;

                rbtnTalla.Location = new Point(250, 40);
                rbtnTalla.Visible = true;
            }
            else
            {
                if (ProductoOriginal.AplicaTalla)
                {
                    CargarTallas();
                    dgvListaMedida.Visible = true;
                    gbSeleccionarMedida.Visible = true;
                    lbUnidadMedida.Visible = false;
                    lbValorMedida.Visible = false;
                    lstbTalla.Visible = false;
                    rbtnTalla.Visible = false;
                    rbtnUnidadMedida.Visible = false;
                }
                else
                {
                    OptionPane.MessageError
                        ("No se puede agregar mas de una medida al producto.");
                }
            }
        }

        private void btnEliminarMedida_Click(object sender, EventArgs e)
        {
            if (dgvColor.RowCount == 0)
            {
                if (dgvMedida.RowCount != 0)
                {
                    DialogResult result = MessageBox.Show("Esta seguro que quiere eliminar el registro?", "Producto",
                        MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (result == DialogResult.Yes)
                    {
                        var idMedida = (int)dgvMedida.CurrentRow.Cells[0].Value;
                        var inventario = new DTO.Clases.Inventario();
                        inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                        inventario.IdMedida = idMedida;
                        try
                        {
                            if (miBussinesInventario.EliminarInventario(inventario))
                            {
                                miBussinesMedida.EliminarProductoMedida(ProductoOriginal.CodigoInternoProducto, idMedida);
                                CargarMedida();
                                dgvMedida_CellClick(null, null);
                            }
                            else
                            {
                                OptionPane.MessageError
                                    ("El registro no se puede eliminar porque aun se encuentra en inventario.");
                            }
                        }
                        catch (InvalidCastException)
                        {
                            miBussinesMedida.EliminarProductoMedida(ProductoOriginal.CodigoInternoProducto, idMedida);
                            CargarMedida();
                            dgvMedida_CellClick(null, null);
                            //OptionPane.MessageError(ex.Message);
                        }
                    }
                }
            }
            else
            {
                OptionPane.MessageInformation
                    ("Debe eliminar todos los colores asociados a la medida.");
            }
            if (dgvMedida.RowCount == 0)
            {
                ProductoEditado.AplicaTalla = false;
            }
        }

        private void btnElegirMedida_Click(object sender, EventArgs e)
        {
            int idSelect = 0;
            if (dgvMedida.RowCount != 0) //Selecciona Talla.
            {
                foreach (DataGridViewRow row in dgvListaMedida.SelectedRows)
                {
                    var existe = true;
                    foreach (DataGridViewRow row_ in dgvMedida.Rows)
                    {
                        idSelect = (int)row.Cells[0].Value;
                        var id = (int)row_.Cells[0].Value;
                        if (idSelect == id)
                        {
                            existe = false;
                            break;
                        }
                        else
                        {
                            existe = true;
                        }
                    }
                    if (existe)
                    {
                        var inventario = new DTO.Clases.Inventario();
                        inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                        inventario.IdMedida = idSelect;
                        var medida = new ValorUnidadMedida();
                        medida.CodigoInternoProducto = ProductoOriginal.CodigoInternoProducto;
                        medida.IdValorUnidadMedida = idSelect;
                        try
                        {
                            //miBussinesInventario.InsertarInventario(inventario);
                            miBussinesMedida.InsertarMedidaProducto(medida);
                        }
                        catch (Exception ex)
                        {
                            OptionPane.MessageError(ex.Message);
                        }
                    }
                }
            }
            else
            {
                int idMedida = 0;
                var inventario = new DTO.Clases.Inventario();
                inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                if (rbtnUnidadMedida.Checked)
                {
                    idMedida = Convert.ToInt32(lbValorMedida.SelectedValue);
                    ProductoOriginal.AplicaTalla = false;
                }
                else
                {
                    idMedida = Convert.ToInt32(lstbTalla.SelectedValue);
                    ProductoOriginal.AplicaTalla = true;
                }
                inventario.IdMedida = idMedida;
                var medida = new ValorUnidadMedida();
                medida.CodigoInternoProducto = ProductoOriginal.CodigoInternoProducto;
                medida.IdValorUnidadMedida = idMedida;
                try
                {
                    //miBussinesInventario.InsertarInventario(inventario);
                    miBussinesMedida.InsertarMedidaProducto(medida);
                }
                catch (Exception ex)
                {
                    OptionPane.MessageError(ex.Message);
                }
            }
            CargarMedida();
            dgvMedida_CellClick(null, null);
            gbSeleccionarMedida.Visible = false;
            dgvColor.Visible = true;
            btnAddColor.Visible = true;
            btnEliminarColor.Visible = true;
        }

        private void btnCancelarMedida_Click(object sender, EventArgs e)
        {
            gbSeleccionarMedida.Visible = false;
            dgvColor.Visible = true;
            btnAddColor.Visible = true;
            btnEliminarColor.Visible = true;
        }

        private void btnAddColor_Click(object sender, EventArgs e)
        {
            gbSelecionarColor.Visible = true;
            CargarGridColor();
        }

        private void btnEliminarColor_Click(object sender, EventArgs e)
        {
            if (dgvColor.RowCount != 0)
            {
                DialogResult result = MessageBox.Show("Esta seguro que quiere eliminar el registro?", "Producto",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                OptionPane.MessageInformation("Si es el ultimo color del registro se eliminara su medida relacionada.");
                var r = dgvColor.RowCount;
                if (result == DialogResult.Yes)
                {
                    var idColor = (int)dgvColor.CurrentRow.Cells[0].Value;
                    var idMedida = (int)dgvMedida.CurrentRow.Cells[0].Value;
                    var inventario = new DTO.Clases.Inventario();
                    inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                    inventario.IdMedida = idMedida;
                    inventario.IdColor = idColor;
                    try
                    {
                        if (miBussinesInventario.EliminarInventario(inventario))
                        {
                            if (dgvColor.RowCount == 1)
                            {
                                miBussinesMedida.EliminarProductoMedida
                                    (ProductoOriginal.CodigoInternoProducto,
                                      Convert.ToInt32(dgvMedida.CurrentRow.Cells[0].Value));
                            }
                            CargarMedida();
                            dgvMedida_CellClick(null, null);
                        }
                        else
                        {
                            OptionPane.MessageError
                                ("El registro no se puede eliminar porque aun se encuentra en inventario.");
                        }
                    }
                    catch (Exception ex)
                    {
                        OptionPane.MessageError(ex.Message);
                    }
                }
            }
            if (dgvColor.RowCount == 1)
            {
                ProductoEditado.AplicaColor = false;
            }
            if (dgvMedida.RowCount == 1)
            {
                ProductoEditado.AplicaTalla = false;
            }
        }

        private void btnAgregarColor_Click(object sender, EventArgs e)
        {
            var miColor = new ElColor();
            miColorDialog = new ColorDialog();
            miColorDialog.AllowFullOpen = true;
            if (miColorDialog.ShowDialog() == DialogResult.OK)
            {
                if (!ExisteColor())
                {
                    miColor.MapaBits = ImagenComoString();
                    try
                    {
                        miBussinesColor.InsertarColor(miColor);
                    }
                    catch (Exception ex)
                    {
                        OptionPane.MessageError(ex.Message);
                    }
                    CargarGridColor();
                }
                else
                {
                    MessageBox.Show("El color seleccionado ya existe.", "Producto",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private void btnElegirColor_Click(object sender, EventArgs e)
        {
            int idSelect = 0;
            if (dgvColor.RowCount != 0)
            {
                foreach (DataGridViewRow row in dgvListaColor.SelectedRows)
                {
                    var existe = true;
                    foreach (DataGridViewRow row_ in dgvColor.Rows)
                    {
                        idSelect = (int)row.Cells[0].Value;
                        var id = (int)row_.Cells[0].Value;
                        if (idSelect == id)
                        {
                            existe = false;
                            break;
                        }
                        else
                        {
                            existe = true;
                        }
                    }
                    if (existe)
                    {
                        var inventario = new DTO.Clases.Inventario();
                        inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                        inventario.IdMedida = (int)dgvMedida.CurrentRow.Cells[0].Value;
                        inventario.IdColor = idSelect;
                        miBussinesInventario.InsertarInventario(inventario);
                        dgvMedida_CellClick(null, null);
                    }
                }
            }
            else
            {
                var inventario = new DTO.Clases.Inventario();
                inventario.CodigoProducto = ProductoOriginal.CodigoInternoProducto;
                inventario.IdMedida = (int)dgvMedida.CurrentRow.Cells[0].Value;
                inventario.IdColor = (int)dgvListaColor.CurrentRow.Cells[0].Value;
                miBussinesInventario.InsertarInventario(inventario);
                dgvMedida_CellClick(null, null);
            }
        }

        private void btnCancelarColor_Click(object sender, EventArgs e)
        {
            gbSelecionarColor.Visible = false;
        }

        /// <summary>
        /// Carga los datos del producto a editar en el formulario.
        /// </summary>
        private void CargarProductoAEditar()
        {
            try
            {
                ProductoOriginal = miBussinesProducto.ProductoCompleto(CodigoProducto);
                txtCodigo.Text = ProductoOriginal.CodigoInternoProducto;
                txtBarras.Text = ProductoOriginal.CodigoBarrasProducto;
                txtReferencia.Text = ProductoOriginal.ReferenciaProducto;
                txtNombre.Text = ProductoOriginal.NombreProducto;
                txtDescripcion.Text = ProductoOriginal.DescripcionProducto;
                CodigoCategoria = ProductoOriginal.CodigoCategoria;
                txtCategoria.Text = ProductoOriginal.NombreCategoria;
                IdMarca = ProductoOriginal.IdMarca;
                txtMarca.Text = ProductoOriginal.NombreMarca;
                txtUtilidad.Text = ProductoOriginal.UtilidadPorcentualProducto.ToString();
                txtValorVenta.Text = ProductoOriginal.ValorVentaProducto.ToString();
                if (ProductoOriginal.CantidadDecimal)
                {
                    chkCantDecimal.Checked = true;
                }
                //CargarDescuentos();
                //CargarRecargos();
                CargarAplicaPrecio();
                CargarIva();
                txtUnidadVenta.Text = ProductoOriginal.UnidadVentaProducto.ToString();
                txtCantMinima.Text = ProductoOriginal.CantidadMinimaProducto.ToString();
                txtCantMaxima.Text = ProductoOriginal.CantidadMaximaProducto.ToString();
                if (ProductoOriginal.EstadoProducto)
                {
                    rbActivo.Checked = true;
                }
                else
                {
                    rbInactivo.Checked = true;
                }
                CargarMedida();
                if (EnableColor)
                {
                    dgvColor.Visible = true;
                    btnAddColor.Visible = true;
                    btnEliminarColor.Visible = true;
                    dgvColor.AutoGenerateColumns = false;
                    dgvMedida_CellClick(null, null);
                }
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Carga el listado de Descuentos y chekea los usados por el Producto.
        /// </summary>
        private void CargarDescuentos()
        {
            try
            {
                chkLstDescuento.DataSource = miBussinesDescuento.ListadoDescuento();
                chkLstDescuento.DisplayMember = "ValorDescuento";
                chkLstDescuento.ValueMember = "IdDescuento";
                for (int i = 0; i < chkLstDescuento.Items.Count; i++)
                {
                    var decsto = (Descuento)chkLstDescuento.Items[i];
                    foreach (Descuento des in ProductoOriginal.Descuentos)
                    {
                        if (decsto.IdDescuento == des.IdDescuento)
                        {
                            chkLstDescuento.SetItemChecked(i, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Carga el listado de Recargos y chekea los usados por el Producto.
        /// </summary>
        private void CargarRecargos()
        {
            try
            {
                chkLstRecargo.DataSource = miBussinesRecargo.ListadoRecargo();
                chkLstRecargo.DisplayMember = "ValorRecargo";
                chkLstRecargo.ValueMember = "IdRecargo";
                for (int i = 0; i < chkLstRecargo.Items.Count; i++)
                {
                    var recargo = (Recargo)chkLstRecargo.Items[i];
                    foreach (Recargo rec in ProductoOriginal.Recargos)
                    {
                        if (recargo.IdRecargo == rec.IdRecargo)
                        {
                            chkLstRecargo.SetItemChecked(i, true);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Carga el ComboBox de aplica precio con las opciones y selecciona la usada por el Producto.
        /// </summary>
        private void CargarAplicaPrecio()
        {
            aplicaPrecio = new AplicarPrecio();
            cbAplicarPrecio.DataSource = aplicaPrecio.lista();
            if (ProductoOriginal.AplicaPrecioPorcentaje)
            {
                txtAplicaPrecio.Text = "Porcentaje";
                cbAplicarPrecio.SelectedValue = 2;
            }
            else
            {
                txtAplicaPrecio.Text = "Valor";
                cbAplicarPrecio.SelectedValue = 1;
            }
        }

        /// <summary>
        /// Carga el ComboBox Iva y selecciona el Iva usado por el Producto.
        /// </summary>
        private void CargarIva()
        {
            try
            {
                cbIvaEditar.DataSource = miBussinesIva.ListadoIva();
                cbIvaEditar.SelectedValue = ProductoOriginal.IdIva;
                txtIva.Text = ProductoOriginal.ValorIva.ToString();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Carga las medidas de un Producto en el formulario.
        /// </summary>
        private void CargarMedida()
        {
            try
            {
                dgvMedida.AutoGenerateColumns = false;
                dgvMedida.DataSource = miBussinesProducto.ProductoConMedida(ProductoOriginal.CodigoInternoProducto);
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Valida de nuevo todos los campos del formulario.
        /// </summary>
        private void ValidacionParaGuardar()
        {
            txtCodigo_Validating(null, null);
            txtBarras_Validating(null, null);
            txtReferencia_Validating(null, null);
            txtNombre_Validating(null, null);
            txtDescripcion_Validating(null, null);
            txtUtilidad_Validating(null, null);
            txtValorVenta_Validating(null, null);
            txtUnidadVenta_Validating(null, null);
            txtCantMinima_Validating(null, null);
            txtCantMaxima_Validating(null, null);
        }

        /// <summary>
        /// Cargar un objeto Producto con los datos del formulario.
        /// </summary>
        private void CargarProducto()
        {
            ProductoEditado.CodigoInternoProducto = ProductoOriginal.CodigoInternoProducto;
            ProductoEditado.CodigoInternoEditado = txtCodigo.Text;
            ProductoEditado.CodigoBarrasProducto = txtBarras.Text;
            ProductoEditado.ReferenciaProducto = txtReferencia.Text;
            ProductoEditado.NombreProducto = txtNombre.Text;
            ProductoEditado.DescripcionProducto = txtDescripcion.Text;
            ProductoEditado.CodigoCategoria = CodigoCategoria;
            ProductoEditado.IdMarca = IdMarca;
            ProductoEditado.UtilidadPorcentualProducto = Convert.ToDouble(txtUtilidad.Text);
            ProductoEditado.ValorVentaProducto = Convert.ToInt32(txtValorVenta.Text);
            if(Convert.ToInt32(cbAplicarPrecio.SelectedValue) == 1)
            {
                ProductoEditado.AplicaPrecioPorcentaje = false;
            }
            ProductoEditado.IdIva = Convert.ToInt32(cbIvaEditar.SelectedValue);
            LlenarDescuentos();
            ProductoEditado.Descuentos = Descuentos;
            LlenarRecargos();
            ProductoEditado.Recargos = Recargos;
            ProductoEditado.UnidadVentaProducto = Convert.ToInt32(txtUnidadVenta.Text);
            ProductoEditado.CantidadMinimaProducto = Convert.ToInt32(txtCantMinima.Text);
            ProductoEditado.CantidadMaximaProducto = Convert.ToInt32(txtCantMaxima.Text);
            if (rbActivo.Checked)
                ProductoEditado.EstadoProducto = true;
            else
                ProductoEditado.EstadoProducto = false;
            if (dgvMedida.RowCount > 1)
                ProductoEditado.AplicaTalla = true;
            else
                ProductoEditado.AplicaTalla = false;
            if (dgvColor.RowCount != 0)
                ProductoEditado.AplicaColor = true;
            else
                ProductoEditado.AplicaColor = false;
            if (chkCantDecimal.Checked)
                ProductoEditado.CantidadDecimal = true;
            else
                ProductoEditado.CantidadDecimal = false;
        }

        /// <summary>
        /// Carga el listado de Descuentos elegidos por el usuario.
        /// </summary>
        private void LlenarDescuentos()
        {
            Descuentos = new List<Descuento>();
            foreach (Descuento des in chkLstDescuento.CheckedItems)
            {
                Descuentos.Add(des);
            }
        }

        /// <summary>
        /// Carga el listado de Recargos elegidos por el usuario.
        /// </summary>
        private void LlenarRecargos()
        {
            Recargos = new List<Recargo>();
            foreach (Recargo re in chkLstRecargo.CheckedItems)
            {
                Recargos.Add(re);
            }
        }

        void CompletaEventos_Completo(CompletaArgumentosDeEventom args)
        {
            try
            {
                var categoria = (DTO.Clases.Categoria)args.MiMarca;
                CodigoCategoria = categoria.CodigoCategoria;
                txtCategoria.Text = categoria.NombreCategoria;
            }
            catch { }

            try
            {
                var marca = (TransferirMarca)args.MiMarca;
                IdMarca = marca.IdMarca;
                txtMarca.Text = marca.NombreMarca;
            }
            catch { }
        }

        /// <summary>
        /// Cargar las tallas en el DataGrid.
        /// </summary>
        private void CargarTallas()
        {
            try
            {
                dgvListaMedida.AutoGenerateColumns = false;
                dgvListaMedida.DataSource = miBussinesMedida.ListadoDeTallas();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Carga las unidades de medida en el List Box.
        /// </summary>
        private void CargarUnidadMedida()
        {
            try
            {
                lbUnidadMedida.DataSource = miBussinesUnidad.ListadoUnidadMedidaNoTalla();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Cargar las tallas en el ListBox.
        /// </summary>
        private void CargarListBoxTallas()
        {
            try
            {
                lstbTalla.DataSource = miBussinesMedida.ListadoDeTallas();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        private void lbUnidadMedida_SelectedValueChanged(object sender, EventArgs e)
        {
            int idMedida = Convert.ToInt32(lbUnidadMedida.SelectedValue);
            CargarValorUnidadMedida(idMedida);
        }

        /// <summary>
        /// Carga los Valores de las unidades de medida segun la medida en el List Box.
        /// </summary>
        /// <param name="idUnidadMedida">Id de la Unidad de Medida a Cargar.</param>
        private void CargarValorUnidadMedida(int idUnidadMedida)
        {
            try
            {
                lbValorMedida.DataSource =
                    miBussinesMedida.ListadoValorUnidadMedida(idUnidadMedida);
                /*if (!EnableColor)
                {
                    lbValorMedida.SelectionMode = SelectionMode.One;
                }*/
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void rbtnUnidadMedida_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtnUnidadMedida.Checked)
            {
                for (int i = 1; i < lstbTalla.Items.Count; i++)
                {
                    lstbTalla.SetSelected(i, false);
                }
                lstbTalla.Enabled = false;
                lbUnidadMedida.Enabled = true;
                lbValorMedida.Enabled = true;
                ProductoEditado.AplicaTalla = false;
            }
        }

        private void rbtnTalla_CheckedChanged(object sender, EventArgs e)
        {
            if (rbtnTalla.Checked)
            {
                lstbTalla.Enabled = true;
                lbUnidadMedida.Enabled = false;
                lbValorMedida.Enabled = false;
                ProductoEditado.AplicaTalla = true;
            }
        }

        private void txtCodigo_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtCodigo, miError, codigoRequerido))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.LetrasGuionNumeros, txtCodigo, miError, codigoFormato))
                {
                    var codigoTemp = txtCodigo.Text;
                    if (ExisteCodigo(txtCodigo.Text) && codigoTemp != ProductoOriginal.CodigoInternoProducto)
                    {
                        codigoMatch = false;
                        miError.SetError(txtCodigo, codigoExiste);
                    }
                    else
                    {
                        codigoMatch = true;
                        miError.SetError(txtCodigo, null);
                    }
                }
                else
                    codigoMatch = false;
            }
            else
                codigoMatch = false;
        }

        private void txtBarras_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtBarras, miError, "El codigo de Barras es Requerido"))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.NumeroGuion, txtBarras, miError, barraFormato))
                {
                    if (ExisteCodigoBarras(txtBarras.Text) && txtBarras.Text != ProductoOriginal.CodigoBarrasProducto)
                    {
                        miError.SetError(txtBarras, barrasExiste);
                        barraMatch = false;
                    }
                    else
                    {
                        miError.SetError(txtBarras, null);
                        barraMatch = true;
                    }
                }
                else
                    barraMatch = false;
            }
            else
                barraMatch = false;
        }

        private void txtReferencia_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtReferencia.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.LetrasGuionNumeros, txtReferencia, miError, referenciaFormato))
                {
                    referenciaMatch = true;
                }
                else
                    referenciaMatch = false;
            }
            else
                referenciaMatch = true;
        }

        private void txtNombre_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtNombre, miError, nombreRequerido))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.PalabrasNumeroCaracter, txtNombre, miError, nombreFormato))
                {
                    nombreMatch = true;
                }
                else
                    nombreMatch = false;
            }
            else
                nombreMatch = false;
        }

        private void txtDescripcion_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtDescripcion.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.PalabrasNumeroCaracter, txtDescripcion, miError, descripcionFormato))
                {
                    descripcionMatch = true;
                }
                else
                    descripcionMatch = false;
            }
            else
                descripcionMatch = true;
        }

        private void txtUtilidad_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtUtilidad.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.NumerosYPunto, txtUtilidad, miError, utilidadFormato))
                {
                    utilidadMatch = true;
                }
                else
                    utilidadMatch = false;
            }
            else
                utilidadMatch = true;
        }

        private void txtValorVenta_Validating(object sender, CancelEventArgs e)
        {
            if (!Validacion.EsVacio(txtValorVenta, miError, valorVentaRequerido))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.Numeros, txtValorVenta, miError, valorVentaFormato))
                {
                    valorVentaMatch = true;
                }
                else
                    valorVentaMatch = false;
            }
            else
                valorVentaMatch = false;
        }

        private void txtUnidadVenta_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtUnidadVenta.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.Numeros, txtUnidadVenta, miError, presentacionFormato))
                {
                    presentacionMatch = true;
                }
                else
                    presentacionMatch = false;
            }
            else
                presentacionMatch = true;
        }

        private void txtCantMinima_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtCantMinima.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.Numeros, txtCantMinima, miError, minimaFormato))
                {
                    minimaMatch = true;
                }
                else
                    minimaMatch = false;
            }
            else
                minimaMatch = true;
        }

        private void txtCantMaxima_Validating(object sender, CancelEventArgs e)
        {
            if (!String.IsNullOrEmpty(txtCantMaxima.Text))
            {
                if (Validacion.ConFormato
                    (Validacion.TipoValidacion.Numeros, txtCantMaxima, miError, maximaFormato))
                {
                    maximaMatch = true;
                }
                else
                    maximaMatch = false;
            }
            else
                maximaMatch = true;
        }

        /// <summary>
        /// Cargar el DataGridView con la lista de colores.
        /// </summary>
        private void CargarGridColor()
        {
            this.dgvListaColor.AutoGenerateColumns = false;
            try
            {
                this.dgvListaColor.DataSource = miBussinesColor.ListadoDeColores();
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
            }
        }

        /// <summary>
        /// Crea un directorio para la pertinencia temporal de archivos.
        /// </summary>
        private void CrearDirectorio()
        {
            if (!System.IO.Directory.Exists(folder))
            {
                System.IO.Directory.CreateDirectory(folder);
                System.IO.File.SetAttributes
                    (folder, System.IO.FileAttributes.Hidden);
            }
        }

        /// <summary>
        /// Almacena el color seleccionado como una imagen en un archivo y carpeta temporal.
        /// </summary>
        private void AlmacenarImagen()
        {
            pbColor.Image = new Bitmap(pbColor.Width, pbColor.Height);
            Graphics grafico = Graphics.FromImage(pbColor.Image);
            grafico.Clear(miColorDialog.Color);
            pbColor.Refresh();
            Rectangle r = new Rectangle(new Point(0, 0),
                new Size(pbColor.Width - 1, pbColor.Height - 1));
            grafico.DrawRectangle(new Pen(System.Drawing.Color.Black, 1), r);
            pbColor.Refresh();
            pbColor.Image.Save(rutaYArchivo, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        /// <summary>
        /// Obtiene un string Base64 que representa el mapa de bits del color, de la imagen almacenada.
        /// </summary>
        /// <returns></returns>
        private string ImagenComoString()
        {
            string sBase64 = "";
            System.IO.FileStream fs = new System.IO.FileStream
                            (rutaYArchivo, System.IO.FileMode.Open);
            System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
            byte[] bytes = new byte[(int)fs.Length];
            try
            {
                br.Read(bytes, 0, bytes.Length);
                sBase64 = Convert.ToBase64String(bytes);
                return sBase64;
            }
            catch
            {
                OptionPane.MessageError("Ocurrio un error al cargar el Color.");
                return null;
            }
            finally
            {
                fs.Close();
                fs = null;
                br = null;
                bytes = null;
            }
        }

        /// <summary>
        /// Valida si un color existe en la base de datos.
        /// </summary>
        /// <returns></returns>
        private bool ExisteColor()
        {
            AlmacenarImagen();
            string stringColor = ImagenComoString();
            try
            {
                return miBussinesColor.ExisteColor(stringColor);
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Comprueba si el codigo existe en un registro de Producto.
        /// </summary>
        /// <param name="codigo">Codigo a comprobar.</param>
        /// <returns></returns>
        private bool ExisteCodigo(string codigo)
        {
            try
            {
                return miBussinesProducto.ExisteCodigo(codigo);
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// Comprueba si el codigo existe en un registro de Producto.
        /// </summary>
        /// <param name="codigo">Codigo a comprobar.</param>
        /// <returns></returns>
        private bool ExisteCodigoBarras(string codigo)
        {
            try
            {
                return miBussinesProducto.ExisteCodigoBarras(codigo);
            }
            catch (Exception ex)
            {
                OptionPane.MessageError(ex.Message);
                return false;
            }
        }

    }
}